package com.kmxd.ams.app.event.summary.command;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kmxd.ams.client.archive.IArchiveFieldSvc;
import com.kmxd.ams.client.archive.IArchiveTypeSvc;
import com.kmxd.ams.client.arrange.IBoxSvc;
import com.kmxd.ams.client.arrange.IDocumentSvc;
import com.kmxd.ams.client.arrange.IProjectSvc;
import com.kmxd.ams.client.arrange.IVolumeSvc;
import com.kmxd.ams.client.event.summary.SummaryProjectEvent;
import com.kmxd.ams.core.common.enums.SummaryTypeEnum;
import com.kmxd.ams.core.util.ConvertUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveField;
import com.kmxd.ams.infra.arrange.entity.Box;
import com.kmxd.ams.infra.arrange.entity.Project;
import com.kmxd.ams.infra.arrange.entity.Volume;
import com.kmxd.ams.infra.tmpl.dto.ArchTmplBO;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 汇总项目级信息 按元数据汇总信息设置，进行信息汇总
 *
 * @author nickbi
 */
@Slf4j
@Component
@AllArgsConstructor
public class ProjectSummaryCmd {
  private final IVolumeSvc volumeSvc;
  private final IDocumentSvc documentSvc;
  private final IBoxSvc boxSvc;
  private final IProjectSvc projectSvc;
  private final IArchiveFieldSvc archiveFieldSvc;
  private final IArchiveTypeSvc archiveTypeSvc;

  public void summary(SummaryProjectEvent event) {
    log.debug("start summary volume: {} ", event);
    Project qry = new Project();
    qry.setArchTypeId(event.getArchTypeId());
    qry.setTableId(event.getTableId());
    qry.setId(event.getId());
    Project project = projectSvc.view(qry);
    if (null == project) {
      return;
    }
    // 查询字段设置的统计字段信息
    // 查询字段设置的统计字段信息
    LambdaQueryWrapper<ArchiveField> wrapper =
        Wrappers.<ArchiveField>lambdaQuery()
            .eq(ArchiveField::getArchTypeId, event.getArchTypeId())
            .eq(ArchiveField::getTableId, event.getTableId())
            .isNotNull(ArchiveField::getSummaryTableId)
            .isNotNull(ArchiveField::getSummaryType)
            .isNotNull(ArchiveField::getSummaryField);
    List<ArchiveField> fieldList = archiveFieldSvc.list(wrapper);
    if (null == fieldList || fieldList.isEmpty()) {
      return;
    }

    Map<String, Object> projectMap = BeanUtil.beanToMap(project);

    fieldList.stream()
        // 过滤空字符串，多个filter编译后会优化，便于阅读代码可以分开编写
        .filter(item -> StringUtils.isNotBlank(item.getSummaryType()))
        .filter(item -> StringUtils.isNotBlank(item.getSummaryTableId()))
        .filter(item -> StringUtils.isNotBlank(item.getSummaryField()))
        .forEach(
            meta -> {
              if (meta.getSummaryTableId().contains(ArchTmplBO.VOLUME)) {
                Volume volume = new Volume();
                volume.setProjId(project.getId());
                volume.setTableId(event.getVolTableId());
                Object summaryValue =
                    volumeSvc.selectWithSummaryType(
                        volume,
                        meta.getSummaryField(),
                        SummaryTypeEnum.convert(meta.getSummaryType()));
                projectMap.put(StringUtils.underlineToCamel(meta.getDbFieldKey()), summaryValue);
              }
              if (meta.getSummaryTableId().contains(ArchTmplBO.BOX)) {
                Box box = new Box();
                box.setProjId(project.getId());
                box.setTableId(event.getBoxTableId());
                Object summaryValue =
                    boxSvc.selectWithSummaryType(
                        box,
                        meta.getSummaryField(),
                        SummaryTypeEnum.convert(meta.getSummaryType()));
                projectMap.put(StringUtils.underlineToCamel(meta.getDbFieldKey()), summaryValue);
              }
            });
    Project newProject = ConvertUtil.toBean(projectMap, Project.class);
    newProject.setTableId(event.getTableId());
    if (newProject.equals(project)) {
      return;
    }
    projectSvc.updateById(newProject);
  }
}
